package com.gui.util;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Created by Gui on 2017/7/19.
 */
public final class RedisOutputStream extends FilterOutputStream {

    protected final byte[] buf;
    protected int count;

    public RedisOutputStream(OutputStream out) {
        this(out, 8 * 1024);
    }

    public RedisOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        this.buf = new byte[size];
    }

    private void flushBuffer() throws IOException {
        if (this.count > 0) {
            this.out.write(this.buf, 0, count);
            this.count = 0;
        }
    }

    @Override
    public void write(int b) throws IOException {
        if (this.count == this.buf.length) {
            this.flushBuffer();
        }
        this.buf[count ++] = (byte) b;
    }

    @Override
    public void write(byte[] b) throws IOException {
        this.write(b, 0, b.length);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        if (len >= this.buf.length) {
            this.flushBuffer();
            this.out.write(b, off, len);
        } else {
            if (len >= buf.length - count) {
                this.flushBuffer();
            }
            System.arraycopy(b, off, buf, count, len);
            this.count += len;
        }
    }

    public void writeAsciiCRLF(String in) throws IOException {
        int size = in.length();
        for (int i = 0; i < size; i ++) {
            if (this.count == this.buf.length) {
                this.flushBuffer();
            }
            this.buf[count ++] = (byte) in.charAt(i);
        }
        this.writeCRLF();
    }

    public void writeCRLF() throws IOException {
        if (2 >= this.buf.length - this.count) {
            this.flushBuffer();
        }
        this.buf[count ++] = Constants.CR;
        this.buf[count ++] = Constants.LF;
    }

    @Override
    public void flush() throws IOException {
        this.flushBuffer();
        this.out.flush();
    }
}
